package org.common.utils.generatormapper.event.handler.generator.service;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.common.utils.field.FieldInfo;
import org.common.utils.tool.StringTool;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

/**
 * @author zhouzhibing
 * @date 2025/1/8
 */
public class GeneratorService {

    public static final GeneratorService INSTANCE = new GeneratorService();

    private GeneratorService() {
        initVelocity();

    }

    public static GeneratorService getInstance() {
        return INSTANCE;
    }

    private void initVelocity() {
        Properties props = new Properties();
        props.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        props.put("runtime.references.strict", "false");
        Velocity.init(props);
    }

    public void generator(String writePath , String packageName , String tableName , List<FieldInfo> list) {
        String className = StringTool.toMaxHumpString(tableName);
        String packagePath = packageName.replaceAll("\\.", StringTool.SEPARATOR_ESCAPE);

        generatorAbstractEntity(writePath, packageName, packagePath, className , list);
        generatorEntity(writePath, packageName, packagePath, className , list);
        generatorMapper(writePath , packageName , packagePath, className , tableName, list);
    }

    private void checkPath(String writePath, String packagePath) {
        String allPath = writePath + File.separator + packagePath;
        File file = new File(allPath);
        if(!file.exists()) {
            file.mkdirs();
        }
    }

    private void generatorMapper(String writePath, String packageName, String packagePath, String className, String tableName , List<FieldInfo> fieldList) {
        String entityClassName = className;
        className = className + "Mapper";
        String fileName = className + ".java";
        String filePath = writePath + File.separator + packagePath + File.separator + fileName;

        VelocityContext context = new VelocityContext();
        context.put("fileName", fileName);
        context.put("className", className);
        context.put("tableName", tableName);
        context.put("entityClassName", entityClassName);
        context.put("packageName", packageName);
        context.put("fieldList", fieldList);

        try (FileWriter writer = new FileWriter(filePath)) {
            Template template = Velocity.getTemplate("velocity/mapper.vm", "UTF-8");
            template.merge(context , writer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void generatorEntity(String writePath, String packageName, String packagePath, String className, List<FieldInfo> fieldList) {
        String fileName = className + ".java";
        String filePath = writePath + File.separator + packagePath + File.separator + fileName;

        VelocityContext context = new VelocityContext();
        context.put("fileName", fileName);
        context.put("className", className);
        context.put("packageName", packageName);
        context.put("fieldList", fieldList);

        try (FileWriter writer = new FileWriter(filePath)) {
            Template template = Velocity.getTemplate("velocity/entity.vm", "UTF-8");
            template.merge(context , writer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void generatorAbstractEntity(String writePath , String packageName , String packagePath, String className, List<FieldInfo> fieldList) {
        className = "Abstract" + className;
        String fileName = className + ".java";
        String filePath = writePath + File.separator + packagePath + File.separator + fileName;

        VelocityContext context = new VelocityContext();
        context.put("fileName", fileName);
        context.put("className", className);
        context.put("packageName", packageName);
        context.put("fieldList", fieldList);

        try (FileWriter writer = new FileWriter(filePath)) {
            Template template = Velocity.getTemplate("velocity/abstract_entity.vm", "UTF-8");
            template.merge(context , writer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
